#include "tools/json.h"

// 值构造------------------------------------------------------------
JsonValue *json_create_null() {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_NULL;
    return v;
}

JsonValue *json_create_bool(int b) {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_BOOL;
    v->value.boolean = b ? 1 : 0;
    return v;
}

JsonValue *json_create_number(double num) {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_NUMBER;
    v->value.number = num;
    return v;
}

JsonValue *json_create_string(const char *str) {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_STRING;
    v->value.string = strdup(str);
    return v;
}

JsonValue *json_create_array() {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_ARRAY;
    v->value.array.elements = NULL;
    v->value.array.count = 0;
    v->value.array.capacity = 0;
    return v;
}

JsonValue *json_create_object() {
    JsonValue *v = (JsonValue *)malloc(sizeof(JsonValue));
    v->type = JSON_OBJECT;
    v->value.object.members = NULL;
    v->value.object.count = 0;
    v->value.object.capacity = 0;
    return v;
}

void json_free(JsonValue *value) {
    if (!value) return;
    switch (value->type) {
        case JSON_STRING: free(value->value.string); break;
        case JSON_ARRAY:
            for (size_t i = 0; i < value->value.array.count; i++)
                json_free(value->value.array.elements[i]);
            free(value->value.array.elements);
            break;
        case JSON_OBJECT:
            for (size_t i = 0; i < value->value.object.count; i++) {
                free(value->value.object.members[i].key);
                json_free(value->value.object.members[i].value);
            }
            free(value->value.object.members);
            break;
        default: break;
    }
    free(value);
}


// 数据操作函数-----------------------------------------------------------
// 数组操作
void json_array_append(JsonValue *array, JsonValue *value) {
    if (array->type != JSON_ARRAY) return;
    if (array->value.array.count >= array->value.array.capacity) {
        size_t new_cap = array->value.array.capacity * 2 + 4;
        JsonValue **new_elements = realloc(array->value.array.elements, new_cap * sizeof(JsonValue *));
        if (!new_elements) return;
        array->value.array.elements = new_elements;
        array->value.array.capacity = new_cap;
    }
    array->value.array.elements[array->value.array.count++] = value;
}

// 对象操作
void json_object_add(JsonValue *object, const char *key, JsonValue *value) {
    if (object->type != JSON_OBJECT) return;
    if (object->value.object.count >= object->value.object.capacity) {
        size_t new_cap = object->value.object.capacity * 2 + 4;
        JsonMember *new_members = realloc(object->value.object.members, new_cap * sizeof(JsonMember));
        if (!new_members) return;
        object->value.object.members = new_members;
        object->value.object.capacity = new_cap;
    }
    JsonMember *member = &object->value.object.members[object->value.object.count++];
    member->key = strdup(key);
    member->value = value;
}

JsonValue *json_object_get(const JsonValue *object, const char *key) {
    if (object->type != JSON_OBJECT) return NULL;
    for (size_t i = 0; i < object->value.object.count; i++) {
        if (strcmp(object->value.object.members[i].key, key) == 0)
            return object->value.object.members[i].value;
    }
    return NULL;
}



// json 解析----------------------------------------------------------------------
static void skip_whitespace(const char **str) {
    while (isspace((unsigned char)**str)) (*str)++;
}

// 解析字符串
static char *parse_string_raw(const char **str) {
    if (**str != '"') return NULL;
    (*str)++;
    char *buffer = malloc(256);
    size_t len = 0, cap = 256;
    while (**str != '"') {
        if (**str == '\0') { free(buffer); return NULL; } // 未闭合的字符串
        if (len + 1 >= cap) {
            cap *= 2;
            buffer = realloc(buffer, cap);
        }
        if (**str == '\\') {
            (*str)++;
            switch (**str) {
                case '"': buffer[len++] = '"'; break;
                case '\\': buffer[len++] = '\\'; break;
                case '/': buffer[len++] = '/'; break;
                case 'b': buffer[len++] = '\b'; break;
                case 'f': buffer[len++] = '\f'; break;
                case 'n': buffer[len++] = '\n'; break;
                case 'r': buffer[len++] = '\r'; break;
                case 't': buffer[len++] = '\t'; break;
                case 'u': // Unicode处理（简化版）
                    // 简化为跳过四个字符
                    (*str) += 4;
                    buffer[len++] = '?';
                    break;
                default: free(buffer); return NULL;
            }
        } else {
            buffer[len++] = **str;
        }
        (*str)++;
    }
    (*str)++; // 跳过闭合的引号
    buffer[len] = '\0';
    return realloc(buffer, len + 1);
}


static JsonValue *parse_string(const char **str) {
    char *s = parse_string_raw(str);
    if (!s) return NULL;
    JsonValue *v = json_create_string(s);
    free(s);
    return v;
}

// 解析数字
static JsonValue *parse_number(const char **str) {
    char *end;
    double num = strtod(*str, &end);
    if (end == *str) return NULL;
    *str = end;
    return json_create_number(num);
}

// 解析数组
static JsonValue *parse_array(const char **str) {
    JsonValue *array = json_create_array();
    (*str)++; // 跳过'['
    skip_whitespace(str);
    if (**str == ']') {
        (*str)++;
        return array;
    }
    while (1) {
        JsonValue *element = parse_value(str);
        if (!element) { json_free(array); return NULL; }
        json_array_append(array, element);
        skip_whitespace(str);
        if (**str == ',') {
            (*str)++;
            skip_whitespace(str);
        } else if (**str == ']') {
            (*str)++;
            break;
        } else {
            json_free(array); return NULL;
        }
    }
    return array;
}

// 解析对象
static JsonValue *parse_object(const char **str) {
    JsonValue *object = json_create_object();
    (*str)++; // 跳过'{'
    skip_whitespace(str);
    if (**str == '}') {
        (*str)++;
        return object;
    }
    while (1) {
        char *key = parse_string_raw(str);
        if (!key) { json_free(object); return NULL; }
        skip_whitespace(str);
        if (**str != ':') { free(key); json_free(object); return NULL; }
        (*str)++;
        skip_whitespace(str);
        JsonValue *value = parse_value(str);
        if (!value) { free(key); json_free(object); return NULL; }
        json_object_add(object, key, value);
        free(key);
        skip_whitespace(str);
        if (**str == ',') {
            (*str)++;
            skip_whitespace(str);
        } else if (**str == '}') {
            (*str)++;
            break;
        } else {
            json_free(object); return NULL;
        }
    }
    return object;
}

static JsonValue *parse_true(const char **str) {
    if (strncmp(*str, "true", 4) == 0) {
        *str += 4;
        return json_create_bool(1);
    }
    return NULL; // 无效格式
}

static JsonValue *parse_false(const char **str) {
    if (strncmp(*str, "false", 5) == 0) {
        *str += 5;
        return json_create_bool(0);
    }
    return NULL;
}

static JsonValue *parse_null(const char **str) {
    if (strncmp(*str, "null", 4) == 0) {
        *str += 4;
        return json_create_null();
    }
    return NULL;
}

 JsonValue *parse_value(const char **str) {
    skip_whitespace(str); // 跳过空白字符
    switch (**str) {
        case '{': return parse_object(str);   // 解析对象
        case '[': return parse_array(str);    // 解析数组
        case '"': return parse_string(str);   // 解析字符串
        case 't': return parse_true(str);     // 解析 true
        case 'f': return parse_false(str);    // 解析 false
        case 'n': return parse_null(str);     // 解析 null
        default:  return parse_number(str);   // 解析数字（含负数）
    }
}

// 主解析函数
JsonValue *json_parse(const char *json_str) {
    const char *ptr = json_str;
    return parse_value(&ptr);
}
